/* Copyright (C) 2010 Fredrique Samuels, fredriquesamuels@gmail.com */

/*
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef TRI_GRAPHICS_H_
#define TRI_GRAPHICS_H_

#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>

#include "base/animate.h"
#include "base/vector.h"
#include "base/rectangle.h"

#define GLCLEAR glClear
#define GLCLEARALL GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT
#define GLSETBG glClearColor
#define GLTEXTURE2D GL_TEXTURE_2D
#define GL_UN_BYTE GL_UNSIGNED_BYTE
#define GLSUBIMAGE glTexSubImage2D
#define GLBINDTEXTURE glBindTexture

namespace tri {

class graphics {
public:
	class RGBA{
	public:
		RGBA(int r= 255, int g=255, int b=255, int a=255);
		void set(RGBA& color);
		int red;
		int green;
		int blue;
		int alpha;
	};
	
	class TColor {
		//		friend std::ostream &operator<<( std::ostream&, const graphics::color&);
	public:
		TColor();
		TColor(int r, int g, int b, int a=255);
		TColor(float c[4]);
		TColor(RGBA c);
		~TColor();
		
		graphics::RGBA asRGBA();

		void setRed(int r);
		void setTargetRed(int r, float t);
		int getRed();

		void setGreen(int g);
		void setTargetGreen(int g, float t);
		int getGreen();

		void setBlue(int b);
		void setTargetBlue(int b, float t);
		int getBlue();

		void setAlpha(int a);
		void setTargetAlpha(int a, float t);
		int getAlpha();

		void setValue(int r, int g, int b, int a);
		void setValue(float c[4]);
		void setValue(RGBA rgba);
		void setTargetValue(int r, int g, int b, int a, float t);
		void get_gl_values(float *c);
		void apply();
		void mult(float v);

		TColor copy();

		void print();
private:
		tri::TAniVar r, g, b, a;
	};

	static void setBackgroundColor(TColor* c);
	static void setBackgroundColor(int r, int g, int b, int a);
	static void renderGlyph(float w, float h, TColor * c = NULL,
			TColor *c_bottom = NULL, TColor *c_top_right = NULL,
			TColor *c_bottom_right = NULL, tri::TRectangle* tc = NULL, float x=0,
			float y=0, float z=0, float clip_l=0, float clip_t=0,
			float clip_r=0, float clip_b=0);
	/**
	 * Setup Opengl enviroment
	 */
	static void initGraphics();

	/**
	 * Apply a translation using an TAniVector.
	 */
	static void translate(tri::TAniVector &v);
	static void translate(tri::TVector v);

	/**
	 * Apply a rotation using an TAniVector.
	 */
	static void rotate(tri::TAniVector &v);
	static void rotate(tri::TVector v);
	static void loadname(int id);
	static void pushMatrix();
	static void popMatrix();

	static void reduceVectorToUnitLenght(TVector *vec);
	static void calcNormalVector(const TVector *_v0, const TVector *_v1,
			const TVector *_v2, TVector *out);
	
	
	static unsigned int CELL_SHADING_TEXTURE_ID;
	static void initCellShadingTexture();
	static void bindShader();
};

}

#endif /*GRAPHICS_H_*/
